﻿/*******************************************************************************
 * AAEngine
 * Copyright (c) 2010 Mike Jarosch
 *
 * Original source PushButton Engine:
 * Copyright (C) 2009 PushButton Labs, LLC
 * For more information see http://www.pushbuttonengine.com
 *
 * This file is licensed under the terms of the MIT license, which is included
 * in the "MIT License.txt" file at the root directory of this SDK.
 ******************************************************************************/

using System;
using Microsoft.Xna.Framework;
using AAEngine.Engine;
using AAEngine.Engine.Core;
using AAEngine.Engine.Components;

namespace AAEngine.Rendering2D
{
    public class SimpleSpatialComponent : TickedComponent, IMobileSpatialObject2D
    {
        /// <summary>
        /// The size of the object.
        /// </summary>
        private Vector2 _size = new Vector2(100, 100);
        public Vector2 Size
        {
            get { return _size; }
            set { _size = value; }
        }

        /// <summary>
        /// The position of the object.
        /// </summary>
        private Vector2 _position = Vector2.Zero;
        public Vector2 Position
        {
            get { return _position; }
            set { _position = value; }
        }
        public float X
        {
            get { return _position.X; }
            set { _position.X = value; }
        }

        public float Y
        {
            get { return _position.Y; }
            set { _position.X = value; }
        }

        /// <summary>
        /// The rotation of the object.
        /// </summary>
        private float _rotation = 0;
        public float Rotation
        {
            get { return _rotation; }
            set { _rotation = value; }
        }

        private ISpatialManager2D _spatialManager;
        public ISpatialManager2D SpatialManager
        {
            get
            {
                return _spatialManager;
            }
            set
            {
                if (!IsRegistered)
                {
                    _spatialManager = value;
                    return;
                }

                if (_spatialManager != null)
                {
                    _spatialManager.RemoveSpatialObject(this);
                }

                _spatialManager = value;

                if (_spatialManager != null)
                {
                    _spatialManager.AddSpatialObject(this);
                }
            }
        }

        private Vector2 _velocity = Vector2.Zero;
        public Vector2 Velocity
        {
            get { return _velocity; }
            set { _velocity = value; }
        }

        private float _angularVelocity = 0;
        public float AngularVelocity
        {
            get { return _angularVelocity; }
            set { _angularVelocity = value; }
        }

        public override void OnTick(float deltaTime)
        {
            _position += _velocity * deltaTime;
            _rotation += _angularVelocity * deltaTime;
        }

        public override void OnAdd()
        {
            base.OnAdd();

            if (_spatialManager != null)
            {
                _spatialManager.AddSpatialObject(this);
            }
        }

        public override void OnRemove()
        {
            base.OnRemove();

            if (_spatialManager != null)
            {
                _spatialManager.RemoveSpatialObject(this);
            }
        }

        private ObjectType _objectMask;
        public ObjectType ObjectMask
        {
            get { return _objectMask; }
            set { _objectMask = value; }
        }

        private Box _worldExtents = new Box();
        public virtual Box WorldExtents
        {
            get
            {
                _worldExtents.X = _position.X - _size.X * 0.5f;
                _worldExtents.Y = _position.Y - _size.Y * 0.5f;
                _worldExtents.Width = _size.X;
                _worldExtents.Height = _size.Y;

                return _worldExtents;
            }
        }

        public bool CastRay(Vector2 start, Vector2 end, ObjectType mask, ref RayHitInfo result)
        {
            throw new NotImplementedException();
        }

        public bool PointOccupied(Vector2 position, ObjectType mask, IScene2D scene)
        {
            ContainmentType contains = WorldExtents.Contains(position);
            return contains == ContainmentType.Contains || contains == ContainmentType.Intersects;
        }
    }

}
